package nn;

import java.util.ArrayList;

import org.apache.commons.lang3.tuple.Pair;

public class Neuron {

	private float[] weights;
	//values which will be added to old weights
	float[] deltaWeights;
	//deltaWeights from previous epoch
	float[] prevDeltaWeights;

	private Float bias = null;
	private float biasDelta = 0;
	private float prevBiasDelta = 0;
	private ArrayList<Pair<Neuron, Float>> neighbours;

	
	public void initNeuron(float[] weights){
		int size = weights.length;
		deltaWeights = new float[size];
		prevDeltaWeights = new float[size];
		setWeights(weights);
	}
	
	/**
	 * Returns raw value - result of multiplying weights and s previous layer
	 * values. This result is next used by layer as parameter in activation
	 * function.
	 * 
	 * @param prevLayerResult
	 * @return
	 */
	public float getRawValue(float[] prevLayerResult) {
		float result = 0;
		for (int it = 0; it < prevLayerResult.length; ++it) {
			result = result + (weights[it] * prevLayerResult[it]);
		}
		return result;
	}

	public void setWeights(float[] newWeights) {
		this.weights = newWeights.clone();
	}

	public float[] getWeights() {
		if (weights == null) {
			return new float[1];
		}
		return weights.clone();
	}
	
	public void setDeltaWeights(float[] newWeights) {
		this.deltaWeights = newWeights.clone();
	}

	public float[] getDeltaWeights() {
		if (deltaWeights == null) {
			return new float[1];
		}
		return deltaWeights.clone();
	}
	
	public void setPrevDeltaWeights(float[] newWeights) {
		this.prevDeltaWeights = newWeights.clone();
	}

	public float[] getPrevDeltaWeights() {
		if (prevDeltaWeights == null) {
			return new float[1];
		}
		return prevDeltaWeights.clone();
	}

	public void setBias(float bias) {
		this.bias = bias;

	}

	public Float getBias() {
		return bias;
	}
	
	public float getBiasDelta() {
		return biasDelta;
	}

	public void setBiasDelta(float biasDelta) {
		this.biasDelta = biasDelta;
	}
	
	public float getPrevBiasDelta() {
		return prevBiasDelta;
	}

	public void setPrevBiasDelta(float prevBiasDelta) {
		this.prevBiasDelta = prevBiasDelta;
	}

	public ArrayList<Pair<Neuron, Float>> getNeighbours() {
		return neighbours;
	}

	public void setNeighbours(ArrayList<Pair<Neuron, Float>> neighbours) {
		this.neighbours = neighbours;
	}

	public void addNewNeighbours(ArrayList<Pair<Neuron, Float>> newNeighbours) {
		if (neighbours == null) {
			neighbours = new ArrayList<>();
		}
		if (newNeighbours == null) {
			return;
		}
		for (Pair<Neuron, Float> neighbourd : newNeighbours) {
			neighbours.add(neighbourd);
		}
	}



}
